package com.yingxin.yx.framework.commons.helper;

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import com.yingxin.yx.framework.commons.exception.BizException;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author fanchao
 */
public class ListHelper {

    /**
     * Map<R,T> map = list.stream().collect(Collectors.toMap(Object::getId, Function.identity(), (key1, key2) -> key2));
     */
    public static <T, R> Map<R, T> toMap(Function<T, R> function, Collection<T> collection) {
        if (collection == null || collection.isEmpty()) {
            return new HashMap<>(1);
        } else {
            return collection.stream().collect(Collectors.toMap(function, Function.identity(), (key1, key2) -> key2));
        }
    }

    /**
     * Map<R1,R2> map = list.stream().collect(Collectors.toMap(Object::getId, Object::getName));
     */
    public static <T, R1, R2> Map<R1, R2> toMap(Function<T, R1> function1, Function<T, R2> function2, Collection<T> collection) {
        if (collection == null || collection.isEmpty()) {
            return new HashMap<>(1);
        } else {
            return collection.stream().collect(Collectors.toMap(function1, function2, (key1, key2) -> key2));
        }
    }

    /**
     * List<String> ids = list.stream().map(Object::getId).collect(Collectors.toList());
     */
    public static <T, R> List<R> toList(Function<T, R> function, Collection<T> collection) {
        if (collection == null || collection.isEmpty()) {
            return new ArrayList<>();
        } else {
            return collection.stream().map(function).collect(Collectors.toList());
        }
    }

    /**
     * Set<String> ids = list.stream().map(Object::getId).collect(Collectors.toSet());
     */
    public static <T, R> Set<R> toSet(Function<T, R> function, Collection<T> collection) {
        if (collection == null || collection.isEmpty()) {
            return new HashSet<>();
        } else {
            return collection.stream().map(function).collect(Collectors.toSet());
        }
    }

    /**
     * 一个List集合按n进行分组拆分
     * @param list
     * @param n
     * @return
     * @param <T>
     */
    public static <T> List<List<T>> getListSelfSplit(List<T> list, int n){
        if( CollectionUtil.isEmpty( list ) ){
            throw new BizException("列表空！");
        }
        if( n <= 0 ){
            throw new BizException("分组不能小于等于零！");
        }
        int len = list.size();
        List<List<T>> resultList = Lists.newArrayListWithCapacity( len * 4 / 3 );
        // 获取分组数
        int result = len % n == 0 ? len / n : ( len / n + 1 );
        for( int i = 0; i < result; i++ ){
            resultList.add( list.subList( i * n, Math.min( ( i + 1 ) * n, len ) ) );
        }
        return resultList;
    }

}